package com.ant.backstage.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.ant.backstage.dao.PermissionMapper;
import com.ant.backstage.dao.RoleMapper;
import com.ant.backstage.dao.RolepermissionMapper;
import com.ant.backstage.dao.UserroleMapper;
import com.ant.backstage.facade.ApiReturn;
import com.ant.backstage.facade.code.ApiReturnCode;
import com.ant.backstage.facade.dto.RouteDTO;
import com.ant.backstage.facade.dto.RoutesDto;
import com.ant.backstage.facade.enums.PermissionEnum;
import com.ant.backstage.facade.model.Permission;
import com.ant.backstage.facade.model.Role;
import com.ant.backstage.facade.model.Rolepermission;
import com.ant.backstage.facade.model.Userrole;
import com.ant.backstage.facade.request.power.PermissionAddRequest;
import com.ant.backstage.service.PermissionService;
import ma.glasnost.orika.MapperFacade;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Service("permissionService")
public class PermissionServiceImpl implements PermissionService {

    private static Logger logger = LogManager.getLogger(PermissionServiceImpl.class);

    @Resource
    PermissionMapper permissionMapper;
    @Resource
    RolepermissionMapper rolepermissionMapper;
    @Resource
    UserroleMapper userroleMapper;
    @Resource
    RoleMapper roleMapper;
    @Resource
    MapperFacade mapperFacade;

    @Override
    public List<Permission> selectAllPermission() {
        return permissionMapper.selectAll();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    //TODO 事务
    public ApiReturn addPermission(PermissionAddRequest permissionAddRequest) {
        ApiReturn apiReturn = new ApiReturn();
        Permission per = mapperFacade.map(permissionAddRequest, Permission.class);
        //校验权限标识不能相同
        int count = permissionMapper.selectByPerFalg(per.getPermission());
        if (count >= 1) {
            logger.error("新增权限，权限标识不能重复 permissionAddRequest={}", JSONObject.toJSONString(permissionAddRequest));
            apiReturn.setMsg(ApiReturnCode.PERMISSION_FLAG_REPEAT.getMessage());
            apiReturn.setCode(ApiReturnCode.PERMISSION_FLAG_REPEAT.getCode());
            apiReturn.setData(permissionAddRequest);
            return apiReturn;
        }
        int perId = permissionMapper.insert(per);
        permissionAddRequest.getRoleIds().forEach(item->{
            Rolepermission rolepermission = new Rolepermission();
            rolepermission.setRoleId(Integer.valueOf(item));
            rolepermission.setPermissionId(per.getId());
            rolepermissionMapper.insert(rolepermission);
        });
        apiReturn.setApiReturnCode(ApiReturnCode.SUCCESSFUL);
        return apiReturn;
    }

    @Override
    public Permission selectPerById(int id) {
        return permissionMapper.selectByPrimaryKey(id);
    }

    @Override
    public void updatePerStatus(String statusId, String perId) {
        permissionMapper.updateById(Integer.valueOf(statusId),Integer.valueOf(perId));
    }

    @Override
    public   List<RoutesDto>  findUserPerByUid(String uid) {
        //查用户的角色，拼接路由
        //1.查所有角色id
        List<Userrole> userroles = userroleMapper.selectRoleByUid(uid);
        List<Integer> collect = userroles.stream().map(Userrole::getRoleId).collect(Collectors.toList());
        List<Role> roleList = roleMapper.selectRoleByids(collect);
        List<Rolepermission> rolepermissions = rolepermissionMapper.selectByRoleIds(collect);
        List<Integer> PermissionIds = rolepermissions.stream().map(Rolepermission::getPermissionId).collect(Collectors.toList());
        List<Permission> permissions = permissionMapper.selectByids(PermissionIds);
        logger.info("当前用户所有的角色和权限 roleList={}, permissions={}",
                JSONObject.toJSONString(roleList),JSONObject.toJSONString(permissions));

        List<RoutesDto> objects = new ArrayList<>();

        List<Permission> perFirst = permissions.stream().filter(a ->
                String.valueOf(a.getMenu()).equals(PermissionEnum.FIRST_LEVEL_MENU.getCode())).collect(Collectors.toList());
        //组装路由
        perFirst.stream().forEach(per -> {
            //1. 1级路由
            RouteDTO routeDTO = new RouteDTO();
            routeDTO.setPath(per.getPermissionUrl())
                    .setAccess(per.getPermission())
                    .setComponent(per.getComponent())
                    .setIcon(per.getIcon())
                    .setName(per.getDescription())
                    .setKey(UUID.randomUUID().toString());
            if (per.getPermission().equals("ALL::LOGIN")) {
                routeDTO.setLayout(false);
            }else {
                routeDTO.setLayout(true);
            }
            List<RouteDTO> sonList = this.getSon(permissions, per);
            RoutesDto routesDto = mapperFacade.map(routeDTO, RoutesDto.class);
            routesDto.setRoutes(sonList);
            objects.add(routesDto);
        });
        return objects;
    }

    //校验当前父ID 有没有子id
    public  List<RouteDTO>  getSon(List<Permission> permissions, Permission per) {
        List<RouteDTO> twoMaps = new ArrayList<>();
        permissions.stream().filter(s -> s.getParentId() == per.getId()).forEach(twoPer->{
            RouteDTO routeDTO = new RouteDTO();
            routeDTO.setPath(twoPer.getPermissionUrl())
                    .setAccess(twoPer.getPermission())
                    .setComponent(twoPer.getComponent())
                    .setIcon(twoPer.getIcon())
                    .setName(twoPer.getDescription())
                    .setKey(UUID.randomUUID().toString());
            if (twoPer.getPermission().equals("ALL::LOGIN")) {
                routeDTO.setLayout(false);
            }else {
                routeDTO.setLayout(true);
            }
            twoMaps.add(routeDTO);
        });
        return twoMaps;
    }
}
